<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>模板模式（Template Pattern）</title>
    <!-- 
  JavaScript中的模板模式（Template Pattern）是一种行为设计模式，它定义了一个操作中的算法的骨架，而将一些步骤延迟到子类中。
  模板方法使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。
  在JavaScript中，我们可以使用类来实现模板模式。
  下面是一个简单的例子，展示了如何使用类来实现模板模式：
  ```javascript
  // 定义一个抽象类
  class AbstractClass {
      // 模板方法
      templateMethod() {
          this.primitiveOperation1();
          this.primitiveOperation2();
          console.log('执行模板方法中的通用步骤');
      }

      // 原语操作，需要在子类中实现
      primitiveOperation1() {
          throw new Error('子类必须实现此方法');
      }

      // 原语操作，需要在子类中实现
      primitiveOperation2() {
          throw new Error('子类必须实现此方法');
      }
  }

  // 定义一个具体类
  class ConcreteClassA extends AbstractClass {
      primitiveOperation1() {
          console.log('ConcreteClassA 实现了 primitiveOperation1');
      }

      primitiveOperation2() {
          console.log('ConcreteClassA 实现了 primitiveOperation2');
      }
  }

  // 定义另一个具体类
  class ConcreteClassB extends AbstractClass {
      primitiveOperation1() {
          console.log('ConcreteClassB 实现了 primitiveOperation1');
      }

      primitiveOperation2() {
          console.log('ConcreteClassB 实现了 primitiveOperation2');
      }
  }

  // 使用模板方法
  const classA = new ConcreteClassA();
  classA.templateMethod();

  const classB = new ConcreteClassB();
  classB.templateMethod();
  ```

  在这个例子中，`AbstractClass`定义了一个模板方法`templateMethod`，其中包含了算法的骨架。
  `primitiveOperation1`和`primitiveOperation2`是原语操作，它们需要在子类中实现。
  `ConcreteClassA`和`ConcreteClassB`是具体类，它们实现了`primitiveOperation1`和`primitiveOperation2`，从而定义了算法的具体步骤。
  通过这种方式，模板模式允许你在不改变算法结构的情况下，重新定义算法的某些步骤。
  --></head>
  <body>
    <script>
      // 定义一个抽象类
      class AbstractClass {
        // 模板方法
        templateMethod() {
          this.primitiveOperation1();
          this.primitiveOperation2();
          console.log("执行模板方法中的通用步骤");
        }

        // 原语操作，需要在子类中实现
        primitiveOperation1() {
          throw new Error("子类必须实现此方法");
        }

        // 原语操作，需要在子类中实现
        primitiveOperation2() {
          throw new Error("子类必须实现此方法");
        }
      }

      // 定义一个具体类
      class ConcreteClassA extends AbstractClass {
        primitiveOperation1() {
          console.log("ConcreteClassA 实现了 primitiveOperation1");
        }

        primitiveOperation2() {
          console.log("ConcreteClassA 实现了 primitiveOperation2");
        }
      }

      // 定义另一个具体类
      class ConcreteClassB extends AbstractClass {
        primitiveOperation1() {
          console.log("ConcreteClassB 实现了 primitiveOperation1");
        }

        primitiveOperation2() {
          console.log("ConcreteClassB 实现了 primitiveOperation2");
        }
      }

      // 使用模板方法
      const classA = new ConcreteClassA();
      classA.templateMethod();

      const classB = new ConcreteClassB();
      classB.templateMethod();
    </script>
  </body>
</html>
